#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "../polarssl/sha1.h"
#include "libm_sha1.h"
#include "libm_aux.h"

/*
  sha1_output
  "static" - Can only be seen within this source file.
  
  Consult "polarssl/sha1.h" for more info about the variables
  and functions used in the code below.
*/
static char unsigned *sha1_output(unsigned char *input, unsigned char *output)
{
  int ilen;
  ilen = strlen((char *) input);

  sha1_context sha;

  sha1_starts(&sha);
  sha1_update(&sha, input, ilen);
  sha1_finish(&sha, output);

  return output;
}

char *sha1_hash(char *input, char *hash)
{
  unsigned char output[20];
  sha1_output((unsigned char *) input, output);

  int i;
  char *p = hash;

  *p = '\0';

  //Make conversion to hexadecimal representation and
  //store output step-by-step into char-arr "hash".
  for (i = 0; i < 20; i++)
    {
      sprintf(p, "%.2X", output[i]);
      p += 2;
    }

  return hash;
}

/*
  WARNING: All the function arguments must NOT be constants!
*/
char *sha1_mangos(char *user, char *pass, char *hash, int makeStrUp)
{
  int total_len;
  char *input;

  total_len = strlen(user) + strlen(pass) + 2;

  input = (char *) malloc(total_len);
  if (input == NULL)
    {
      *hash = '\0';
      return NULL;
    }

  *input = '\0';

  if (makeStrUp)
    {
      str_up(user);
      str_up(pass);
    }

  strcat(input, user);
  strcat(input, ":");
  strcat(input, pass);

  sha1_hash(input, hash);
  free(input);

  return hash;
}

/*
  int hex
  "static"
  
  Verifies if the value of char "ch" corresponds to:
  0-9, A-Z or a-z.
*/
static int hex(const char ch)
{
  if (isdigit(ch))
    return 1;
  
  if (islower(ch) && (ch - 'a' < 6))
    return 1;
  
  if (isupper(ch) && (ch - 'A' < 6))
    return 1;
  
  return 0;
}

int sha1_valid(char *hash)
{
  int i, len = strlen(hash);
  if (len != 40) return 0;

  for (i = 0; i < len; i++)
    {
      if (!hex(hash[i]))
	return 0;
    }

  return 1;
}
